<template>
  <div class="effects-ascii">
    <div class="canvas" ref="canvas"></div>
  </div>
</template>

<script lang="ts">
import { Vue, Options } from 'vue-property-decorator';
import * as THREE from 'three';
import { AsciiEffect } from 'three/examples/jsm/effects/AsciiEffect';
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls.js';
const scene =  new THREE.Scene();
const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.y = 150;
camera.position.z = 500;
const pointLight1 = new THREE.PointLight(0xffffff);
pointLight1.position.set(500, 500, 500);
scene.add(pointLight1);
const pointLight2 = new THREE.PointLight(0xffffff, 0.25);
pointLight2.position.set(- 500, - 500, - 500);
scene.add(pointLight2);
const renderer = new THREE.WebGLRenderer({
  alpha: true,
  antialias: true,
});
renderer.debug.checkShaderErrors = false;
renderer.setClearColor(new THREE.Color(), 0);
renderer.setPixelRatio(750 / window.innerWidth);
renderer.shadowMap.enabled = true;
let mesh!: THREE.Mesh;
let sphere!: THREE.Mesh;
let effect!: AsciiEffect;
let controls!: TrackballControls;
const start = Date.now();
@Options({ components: {} })
export default class EffectsAscii extends Vue {
  public rect: DOMRect|null = null;

  public onWindowResize() {
  	camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    effect.setSize(window.innerWidth, window.innerHeight);
  }
  public mounted() {
    this.rect = (this.$el as HTMLElement).getBoundingClientRect();
    renderer.setSize(this.rect.width, this.rect.height, false);
    (this.$refs.canvas as HTMLDivElement).append(renderer.domElement);

    sphere = new THREE.Mesh(new THREE.SphereGeometry(200, 32, 16), new THREE.MeshPhongMaterial({ flatShading: true }));
    scene.add(sphere);
    const plane = new THREE.Mesh(new THREE.PlaneGeometry(400, 400), new THREE.MeshBasicMaterial({ color: 0xe0e0e0 }));
    plane.position.y = -200;
    plane.rotation.x = -Math.PI / 2;
    scene.add(plane);
    effect = new AsciiEffect(renderer, '.:-+*=%@#', { invert: true });
    effect.setSize(window.innerWidth, window.innerHeight);
    effect.domElement.style.color = 'white';
    effect.domElement.style.background = 'black';

    document.body.appendChild(effect.domElement);
    controls = new TrackballControls(camera, effect.domElement);

    renderer.setAnimationLoop(() => {
      const timer = Date.now() - start;

      sphere.position.y = Math.abs(Math.sin(timer * 0.002)) * 150;
      sphere.rotation.x = timer * 0.0003;
      sphere.rotation.z = timer * 0.0002;

      controls.update();
      renderer.render(scene, camera);
    });

    window.addEventListener('resize', this.onWindowResize);
  }
}
</script>

<style lang="postcss" scoped>
  .effects-ascii{
    touch-action: none;
    position: absolute;
    left: 0;top: 0;
    width: 100%;height: 100%;
    background: #98bbd1;
     .canvas{
      position: absolute;
      left: 0;top: 0;
      width: 100%;height: 100%;
       :deep(canvas){
        width: 100%;height: 100%;
      }
    }
  }
</style>
